# Absolute Price Oscillator (APO)

import pandas as pd
import statistics as stats

'''
   @ param in
   DataSet: dataset object list 
   NumPeriodsFast: ema fast periods
   NumPeriodsSlow: ema slow periods
   @ return
   DataSet with AbsolutePriceOscillator, FastExponentialMovingAverage, SlowExponentialMovingAverage data
'''
def cal_apo(DataSet, NumPeriodsFast, NumPeriodsSlow):
	data_set_ = pd.DataFrame(DataSet)
    close = data_set_['close'].astype(float)
	num_periods_fast = NumPeriodsFast
	K_fast = 2 / (num_periods_fast + 1)
	ema_fast = 0
	num_periods_slow = NumPeriodsSlow
	K_slow = 2 / (num_periods_slow + 1)
	ema_slow = 0
	ema_fast_values = []
	ema_slow_values = []
	apo_values = []
	for close_price in close:
		if (ema_fast == 0):
			ema_fast = close_price
			ema_slow = close_price
		else:
			ema_fast = (close_price - ema_fast) * K_fast + ema_fast
			ema_slow = (close_price - ema_slow) * K_slow + ema_slow
		ema_fast_values.append(ema_fast)
		ema_slow_values.append(ema_slow)
		apo_values.append(ema_fast - ema_slow)
	data_set_ = data_set_.assign(FastExponentialMovingAverage=pd.Series(ema_fast_values, index=data_set_.index))
	data_set_ = data_set_.assign(SlowExponentialMovingAverage=pd.Series(ema_slow_values, index=data_set_.index))
	data_set_ = data_set_.assign(AbsolutePriceOscillator=pd.Series(apo_values, index=data_set_.index))
	return data_set_
